/*
 * copy image (from one color space to another)
  * April 2008
 *
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 */

#include "libQccPack.h"
 
#define USG_STRING "[-ci %d:inputcolortype] [-co %d:outputcolortype]  %s:inputimgfile %s:outputimgfile"

int inputcolortype = QCCIMGCOLORTYPE_RGB;
int outputcolortype = QCCIMGCOLORTYPE_RGB; 
QccIMGImage InputImage, OutputImage;


int main(int argc, char *argv[])
{
   QccInit(argc, argv);

   QccIMGImageInitialize(&InputImage);
   QccIMGImageInitialize(&OutputImage);
 
   if (QccParseParameters(argc, argv,
                         USG_STRING,
                         &inputcolortype,
			 &outputcolortype,
                         InputImage.filename,
                         OutputImage.filename))
    QccErrorExit();
   if (inputcolortype == QCCIMGCOLORTYPE_YUV ||
       outputcolortype == QCCIMGCOLORTYPE_YUV)
     printf("No YUV on-disk format support\n");


   // formats refer to on-disk one byte per component format.     
   printf("copy from %s (on-disk colortype %d)  to %s (on-disk colortype %d)\n", 
           InputImage.filename, inputcolortype, OutputImage.filename, 
           outputcolortype);
   // always read as RGB. 
   if (QccIMGImageSetColorType(&InputImage, QCCIMGCOLORTYPE_RGB))
    {
      QccErrorAddMessage("%s: Error calling QccIMGImageSetColorType()",
                         argv[0]);
      QccErrorExit();    
    }

   if (QccIMGImageRead(&InputImage))
    {
      QccErrorAddMessage("%s: Error calling QccIMGImageRead()",
                         argv[0]);
      QccErrorExit();
    }

   int i,j;
   // convert from on-disk to in-memory format
   switch(inputcolortype) {
   case QCCIMGCOLORTYPE_RGB:
     // do nothing
     break;
   case QCCIMGCOLORTYPE_YCbCr:
     for (i=0; i < InputImage.Y.num_rows; i++) {
       for (j=0; j < InputImage.Y.num_cols; j++) {
	 InputImage.U.image[i][j] -= (255.0/2);
	 InputImage.V.image[i][j] -= (255.0/2);
       }
     } 

     break;
   default:
     printf("Error: unknown image color type of %d", inputcolortype);
   }
   

   if (QccIMGImageCopy(&OutputImage, &InputImage)) {
      QccErrorAddMessage("%s: Error calling QccIMGImageCopy()",
                         argv[0]);
      QccErrorExit();
   }

   // convert outputImage to proper on-disk format, if necessary. 
   if (inputcolortype == QCCIMGCOLORTYPE_RGB
       && outputcolortype == QCCIMGCOLORTYPE_YCbCr) {
     for (i=0; i < OutputImage.Y.num_rows; i++) {
       for (j=0; j < OutputImage.Y.num_cols; j++) {
	 QccIMGImageRGBtoJPEG_YCbCr(&OutputImage.Y.image[i][j],
				    &OutputImage.U.image[i][j],
				    &OutputImage.V.image[i][j],
				    (int) InputImage.Y.image[i][j],
				    (int) InputImage.U.image[i][j],
				    (int) InputImage.V.image[i][j]);
	 OutputImage.U.image[i][j] += 127.5;
	 OutputImage.V.image[i][j] += 127.5;
       }

       // write YCbCr values directly as RGB triples. 
       if (QccIMGImageSetColorType(&OutputImage, QCCIMGCOLORTYPE_RGB)) 
	 {
	   QccErrorAddMessage("%s: Error calling QccIMGImageSetColorType()",
			      argv[0]);
	   QccErrorExit();
	 }
       
     }
   }
   else if (inputcolortype == QCCIMGCOLORTYPE_YCbCr
       && outputcolortype == QCCIMGCOLORTYPE_RGB) {
     // input is recognized as YCbCb and written out as RGB (after conversion).
     if (QccIMGImageSetColorType(&OutputImage, QCCIMGCOLORTYPE_YCbCr)) 
       {
	 QccErrorAddMessage("%s: Error calling QccIMGImageSetColorType()",
			    argv[0]);
	 QccErrorExit();
	 
       }
   }
   else if (inputcolortype != outputcolortype) {
     printf("Error: unknown image color conversion from %d to %d", inputcolortype, outputcolortype);
   }
   

    
    if (QccIMGImageWrite(&OutputImage))
    {
      QccErrorAddMessage("%s: Error calling QccIMGImageWrite()",
                         argv[0]);
      QccErrorExit();
    }
    return 0;
}
